import {AxdrType} from "../asn1.axdr/AxdrType";
import {ReverseByteArrayInputStream} from "../ReverseByteArrayInputStream";
import {ReverseByteArrayOutputStream} from "../ReverseByteArrayOutputStream";
import {Buffer} from "buffer";
import {ProxyGetRequestList} from "./ProxyGetRequestList";
import {ProxyGetRequestRecord} from "./ProxyGetRequestRecord";
import {ProxySetRequestList} from "./ProxySetRequestList";
import {ProxySetThenGetRequestList} from "./ProxySetThenGetRequestList";
import {ProxyActionRequestList} from "./ProxyActionRequestList";
import {ProxyActionThenGetRequestList} from "./ProxyActionThenGetRequestList";
import {ProxyTransCommandRequest} from "./ProxyTransCommandRequest";
import {AxdrEnum} from "../asn1.axdr/AxdrEnum";


enum Choice {
    _ERR_NONE_SELECTED = -1,
    PROXY_GET_REQUEST_LIST = 1,
    PROXY_GET_REQUEST_RECORD = 2,
    PROXY_SET_REQUEST_LIST = 3,
    PROXY_SET_THEN_GET_REQUEST_LIST = 4,
    PROXY_ACTION_REQUEST_LIST = 5,
    PROXY_ACTION_THEN_GET_REQUEST_LIST = 6,
    PROXY_TRANS_COMMAND_REQUEST = 7,
}


export class Proxy_Request implements AxdrType{

    dataCode: Buffer | null = null;

    choice: Choice = Choice._ERR_NONE_SELECTED;

    proxyGetRequestList : ProxyGetRequestList | null = null;

    proxyGetRequestRecord : ProxyGetRequestRecord | null = null;

    proxySetRequestList : ProxySetRequestList | null = null;

    proxySetThenGetRequestList : ProxySetThenGetRequestList | null = null;

    proxyActionRequestList : ProxyActionRequestList | null = null;

    proxyActionThenGetRequestList : ProxyActionThenGetRequestList | null = null;

    proxyTransCommandRequest : ProxyTransCommandRequest | null = null;

    constructor() {
    }

    set_dataCode(dataCode: Buffer){
        this.dataCode = dataCode;
    }

    setProxyGetRequestList(proxyGetRequestList : ProxyGetRequestList){
        this.resetChoices();
        this.choice = Choice.PROXY_GET_REQUEST_LIST;
        this.proxyGetRequestList = proxyGetRequestList;
    }

    setProxyGetRequestRecord(proxyGetRequestRecord : ProxyGetRequestRecord){
        this.resetChoices();
        this.choice = Choice.PROXY_GET_REQUEST_RECORD;
        this.proxyGetRequestRecord = proxyGetRequestRecord;
    }

    setProxySetRequestList(proxySetRequestList : ProxySetRequestList){
        this.resetChoices();
        this.choice = Choice.PROXY_SET_REQUEST_LIST;
        this.proxySetRequestList = proxySetRequestList;
    }

    setProxySetThenGetRequestList(proxySetThenGetRequestList : ProxySetThenGetRequestList){
        this.resetChoices();
        this.choice = Choice.PROXY_SET_THEN_GET_REQUEST_LIST;
        this.proxySetThenGetRequestList = proxySetThenGetRequestList;
    }

    setProxyActionRequestList(proxyActionRequestList : ProxyActionRequestList){
        this.resetChoices();
        this.choice = Choice.PROXY_ACTION_REQUEST_LIST;
        this.proxyActionRequestList = proxyActionRequestList;
    }

    setProxyActionThenGetRequestList(proxyActionThenGetRequestList : ProxyActionThenGetRequestList){
        this.resetChoices();
        this.choice = Choice.PROXY_ACTION_THEN_GET_REQUEST_LIST;
        this.proxyActionThenGetRequestList = proxyActionThenGetRequestList;
    }

    setProxyTransCommandRequest(proxyTransCommandRequest : ProxyTransCommandRequest){
        this.resetChoices();
        this.choice = Choice.PROXY_TRANS_COMMAND_REQUEST;
        this.proxyTransCommandRequest = proxyTransCommandRequest;
    }

    decode(input: ReverseByteArrayInputStream): number {
        let codeLength = 0;
        let choosen = new AxdrEnum();
        choosen.set_const();

        codeLength += choosen.decode(input);
        this.resetChoices();
        this.choice = choosen.getValue();

        if (this.choice == Choice.PROXY_GET_REQUEST_LIST) {
            this.proxyGetRequestList = new ProxyGetRequestList();
            codeLength += this.proxyGetRequestList.decode(input);
            return codeLength;
        }else if (this.choice == Choice.PROXY_GET_REQUEST_RECORD) {
            this.proxyGetRequestRecord = new ProxyGetRequestRecord();
            codeLength += this.proxyGetRequestRecord.decode(input);
            return codeLength;
        }else if (this.choice == Choice.PROXY_SET_REQUEST_LIST) {
            this.proxySetRequestList = new ProxySetRequestList();
            codeLength += this.proxySetRequestList.decode(input);
            return codeLength;
        }else if (this.choice == Choice.PROXY_SET_THEN_GET_REQUEST_LIST) {
            this.proxySetThenGetRequestList = new ProxySetThenGetRequestList();
            codeLength += this.proxySetThenGetRequestList.decode(input);
            return codeLength;
        }else if (this.choice == Choice.PROXY_ACTION_REQUEST_LIST) {
            this.proxyActionRequestList = new ProxyActionRequestList();
            codeLength += this.proxyActionRequestList.decode(input);
            return codeLength;
        }else if (this.choice == Choice.PROXY_ACTION_THEN_GET_REQUEST_LIST) {
            this.proxyActionThenGetRequestList = new ProxyActionThenGetRequestList();
            codeLength += this.proxyActionThenGetRequestList.decode(input);
            return codeLength;
        }else if (this.choice == Choice.PROXY_TRANS_COMMAND_REQUEST) {
            this.proxyTransCommandRequest = new ProxyTransCommandRequest();
            codeLength += this.proxyTransCommandRequest.decode(input);
            return codeLength;
        }
        throw new Error("Error decoding AxdrChoice: Identifier matched to no item.");
    }

    encode(output: ReverseByteArrayOutputStream): number {
        if (this.dataCode != null) {
            for (let i = this.dataCode.length - 1; i >= 0; i--) {
                output.write(this.dataCode[i]);
            }
            return this.dataCode.length;

        }
        if (this.choice == Choice._ERR_NONE_SELECTED) {
            throw new Error("Error encoding AxdrChoice: No item in choice was selected.");
        }

        let codeLength = 0;

        if (this.choice == Choice.PROXY_TRANS_COMMAND_REQUEST) {
            if(this.proxyTransCommandRequest != null){
                codeLength += this.proxyTransCommandRequest.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(7);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("proxyTransCommandRequest is null");
            }
        }else if (this.choice == Choice.PROXY_ACTION_THEN_GET_REQUEST_LIST) {
            if(this.proxyActionThenGetRequestList != null){
                codeLength += this.proxyActionThenGetRequestList.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(6);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("proxyActionThenGetRequestList is null");
            }
        } else if (this.choice == Choice.PROXY_ACTION_REQUEST_LIST) {
            if(this.proxyActionRequestList != null){
                codeLength += this.proxyActionRequestList.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(5)
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("proxyActionRequestList is null");
            }
        }else if (this.choice == Choice.PROXY_SET_THEN_GET_REQUEST_LIST) {
            if(this.proxySetThenGetRequestList != null){
                codeLength += this.proxySetThenGetRequestList.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(4);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("proxySetThenGetRequestList is null");
            }
        }else if (this.choice == Choice.PROXY_SET_REQUEST_LIST) {
            if(this.proxySetRequestList != null){
                codeLength += this.proxySetRequestList.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(3);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("proxySetRequestList is null");
            }
        }else if (this.choice == Choice.PROXY_GET_REQUEST_RECORD) {
            if(this.proxyGetRequestRecord != null){
                codeLength += this.proxyGetRequestRecord.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(2)
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("proxyGetRequestRecord is null");
            }
        }else if (this.choice == Choice.PROXY_GET_REQUEST_LIST) {
            if(this.proxyGetRequestList != null){
                codeLength += this.proxyGetRequestList.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(1);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("proxyGetRequestList is null");
            }
        }
        throw new Error("Error encoding AxdrChoice: No item in choice was encoded.");
    }

    encodeAndSave(encodingSizeGuess: number) {
        let revOStream = new ReverseByteArrayOutputStream();
        revOStream.setBufSize(encodingSizeGuess);
        this.encode(revOStream);
        this.dataCode = revOStream.getArray();
    }

    getChoiceIndex(): Choice {
        return this.choice;
    }

    resetChoices() {
        this.choice = Choice._ERR_NONE_SELECTED;
        this.proxyGetRequestList = null;
        this.proxyGetRequestRecord = null;
        this.proxySetRequestList = null
        this.proxySetThenGetRequestList = null;
        this.proxyActionRequestList = null;
        this.proxyActionThenGetRequestList = null;
        this.proxyTransCommandRequest = null;
    }

    toString(): string {
        if (this.choice == Choice.PROXY_GET_REQUEST_LIST) {
            if (this.proxyGetRequestList != null) {
                return "choice: {proxyGetRequestList: " + this.proxyGetRequestList + "}";
            } else {
                return "choice is proxyGetRequestList but proxyGetRequestList is null";
            }
        }else if(this.choice == Choice.PROXY_GET_REQUEST_RECORD){
            if(this.proxyGetRequestRecord != null){
                return "choice: {proxyGetRequestRecord: " + this.proxyGetRequestRecord + "}";
            }else{
                return "choice is proxyGetRequestRecord but proxyGetRequestRecord is null";
            }
        }else if(this.choice == Choice.PROXY_SET_REQUEST_LIST){
            if(this.proxySetRequestList != null){
                return "choice: {proxySetRequestList: " + this.proxySetRequestList + "}";
            }else{
                return "choice is proxySetRequestList but proxySetRequestList is null";
            }
        }else if(this.choice == Choice.PROXY_SET_THEN_GET_REQUEST_LIST){
            if(this.proxySetThenGetRequestList != null){
                return "choice: {proxySetThenGetRequestList: " + this.proxySetThenGetRequestList + "}";
            }else{
                return "choice is proxySetThenGetRequestList but proxySetThenGetRequestList is null";
            }
        }else if(this.choice == Choice.PROXY_ACTION_REQUEST_LIST){
            if(this.proxyActionRequestList != null){
                return "choice: {proxyActionRequestList: " + this.proxyActionRequestList + "}";
            }else{
                return "choice is proxyActionRequestList but proxyActionRequestList is null";
            }
        } else if(this.choice == Choice.PROXY_ACTION_THEN_GET_REQUEST_LIST){
            if(this.proxyActionThenGetRequestList != null){
                return "choice: {proxyActionThenGetRequestList: " + this.proxyActionThenGetRequestList + "}";
            }else{
                return "choice is proxyActionThenGetRequestList but proxyActionThenGetRequestList is null";
            }
        }else if(this.choice == Choice.PROXY_TRANS_COMMAND_REQUEST){
            if(this.proxyTransCommandRequest != null){
                return "choice: {proxyTransCommandRequest: " + this.proxyTransCommandRequest + "}";
            }else{
                return "choice is proxyTransCommandRequest but proxyTransCommandRequest is null";
            }
        }else {
            return "unknown";
        }
    }

}
